/*******************************************************************************

                          应用相关回调实现

*******************************************************************************/
#ifdef SUPPORT_EX_PREINCLUDE//不支持Preinlude時
  #include "Preinclude.h"
#endif

#include "IoCtrl.h"
#include "Color.h"

//---------------------------------得到开机底色-------------------------------
//开机时将用此色清屏，可用于准备入场动画的底色
Color_t TftDbi_cbGetInitBg(void)
{
  return DEFAULT_COLOR_BG;
}

/*****************************************************************************
                          BusSlvUsart回调函数
******************************************************************************/
#include "BusSlvUsart.h"
#include "ModbusCodec.h"
#include "cBootDcl.h"
//-----------------------------数据处理函数--------------------------------
//接收完数据后将调用此函数
//此函数内，应负责处理pBus->DataBuf缓冲区里的数据,并将处理结果返回
//返回-1表示错误;  0:数据正确，但不返回数据 
//其它:返回数据个数
signed short BusSlvUsart_cbDataPro(struct _BusSlvUsart *pBus,
                                    unsigned short RcvData,//接收数据长度
                                    unsigned char SlvAdr) //从机地址
{
  //Modbus协议时
  signed short Resume = ModbusCodec_Slv(pBus->DataBuf, RcvData, SlvAdr);
  if(Resume >= 0) return Resume;//处理完成
  //修改名称协议时(暂略)
  
  return 0;
}

/*****************************************************************************
                         USBvCOM回调函数实现
******************************************************************************/
#include "USBvCom.h"
//-----------------------------发送完数据后通报-------------------------------
//此函数在GrpPacket_GetSendPacket()中调用
void GrpPacket_cbSendFinalNotify(const struct _GrpPacket *pGrpPacket)
{
  
}

//-----------------------------按收数据处理函数-------------------------------
//要发送数据时，需按“上层填充数据相关函数”调用以填充数据
//若需清空接收缓冲数据，则返回非0，否则返回0
signed char GrpPacket_cbRcvDataPro(struct _GrpPacket *pGrpPacket)
{
  unsigned short RcvCount = GrpPacket_GetRcvCount(pGrpPacket);
  if(RcvCount == 0) return -1;//异常
  //copy到发送缓冲区,以使其可接收
  __disable_irq();
  GrpPacket_StartFullSend(pGrpPacket);
  unsigned char *pData = GrpPacket_GetSendBuf(pGrpPacket);
  memcpy(pData, GrpPacket_GetRcvBuf(pGrpPacket), RcvCount);
  GrpPacket_RstRcvBuf(pGrpPacket); //处理过程中底层可继续收数
  __enable_irq();
  signed short Resume = ModbusCodec_Slv(pData, RcvCount, 
                                        Usart_pcbGetCfg(0)->U.S.Adr);
  if(Resume >= 0){//有数据要发送了
    GrpPacket_EndFullSend(pGrpPacket, Resume);
  }
  return 0; //已经复位过了
}

/*******************************************************************************
                           Flsh的SPI定义函数实现
*******************************************************************************/

//Bit0123转至IO:
//Sio0: D8, Sio1:D7, Sio2: D3  Sio3: D4
static const unsigned short _Bit0123ToIo[] = {
  (0 << 4) |  (0 << 3) |   (0 << 7) |   ((unsigned short)0 << 8),
  (0 << 4) |  (0 << 3) |   (0 << 7) |   ((unsigned short)1 << 8),
  (0 << 4) |  (0 << 3) |   (1 << 7) |   ((unsigned short)0 << 8),
  (0 << 4) |  (0 << 3) |   (1 << 7) |   ((unsigned short)1 << 8),
  (0 << 4) |  (1 << 3) |   (0 << 7) |   ((unsigned short)0 << 8),
  (0 << 4) |  (1 << 3) |   (0 << 7) |   ((unsigned short)1 << 8),
  (0 << 4) |  (1 << 3) |   (1 << 7) |   ((unsigned short)0 << 8),
  (0 << 4) |  (1 << 3) |   (1 << 7) |   ((unsigned short)1 << 8),  
  (1 << 4) |  (0 << 3) |   (0 << 7) |   ((unsigned short)0 << 8),
  (1 << 4) |  (0 << 3) |   (0 << 7) |   ((unsigned short)1 << 8),
  (1 << 4) |  (0 << 3) |   (1 << 7) |   ((unsigned short)0 << 8),
  (1 << 4) |  (0 << 3) |   (1 << 7) |   ((unsigned short)1 << 8),
  (1 << 4) |  (1 << 3) |   (0 << 7) |   ((unsigned short)0 << 8),
  (1 << 4) |  (1 << 3) |   (0 << 7) |   ((unsigned short)1 << 8),
  (1 << 4) |  (1 << 3) |   (1 << 7) |   ((unsigned short)0 << 8),
  (1 << 4) |  (1 << 3) |   (1 << 7) |   ((unsigned short)1 << 8),   
};

//--------------------------------写SIO4-----------------------------------
void SPI2_WrSIO4(unsigned char Bit0123) //函数实现
{
  //一写次性写入
  GPIOD->ODR = (GPIOD->ODR & ~SIO4_MASK) | _Bit0123ToIo[Bit0123];
}

//--------------------------------读SIO4-----------------------------------
unsigned char SPI2_RdSIO4(void)
{
  unsigned short Data = GPIOD->IDR;//一次性读出
  unsigned char Bit0123 = 0;
  if(Data & ((unsigned short)1 << 8)) Bit0123 += 1;
  if(Data & ((unsigned short)1 << 7)) Bit0123 += 2;
  if(Data & ((unsigned short)1 << 3)) Bit0123 += 4;
  if(Data & ((unsigned short)1 << 4)) Bit0123 += 8; 
  return Bit0123;
}

/*******************************************************************************
                             ModbusCodec回调实现
*******************************************************************************/
extern unsigned char AutoAppTimer; //自动进BOOT倒计时

//-------------------------作为从机时编码函数--------------------------------
////返回-1表示错误;  0:数据正确，但不返回数据, 其它:返回数据个数(含地址)
signed short ModbusCodec_cbEncoder(unsigned char *pData,//功能码开始
                                    unsigned short RcvLen)//接收数据长度
{
  //if(RcvLen < 6) return -1;//异常->上层有保证
  unsigned char FunCode = *pData;
  if(FunCode == 67){//cBootDcl
    AutoAppTimer = AUTO_APP_OV; //自动进BOOT倒计时恢复
    signed char Resume = cBootDcl_RcvPro(pData + 1, RcvLen - 1);
    if(Resume > 0) return Resume + 2; //加功能码与地址
  }
  else if(FunCode < 64){//不支持的标准功能码
    *pData |= 0x80; //返回错误
    return 2; //功能码与地址
  }
  return -1;//不支持的协议段
}













